package cn.bounce;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;


public class Bounce {
    public static void main(String[] args) {
        EventQueue.invokeLater(
                () -> {
                    JFrame frame = new BounceFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setVisible(true);
                });
    }
}

/**
 * The frame with ball component and buttons.
 */
class BounceFrame extends JFrame {
    private BallComponent comp;
    public static final int STEPS = 1000000;
    public static final int DELAY = 2;

    /**
     * Constructs the frame with the component for showing the bouncing ball and
     * 3s
     * Start and Close buttons
     * V
     */
    public BounceFrame() {
        setTitle("Bounce");
        comp = new BallComponent();
        add(comp, BorderLayout.CENTER);

        JPanel buttonPanel = new JPanel();
        addButton(buttonPanel, "Start", event -> addBall());
        addButton(buttonPanel, "Close", event -> System.exit(0));
        add(buttonPanel, BorderLayout.SOUTH);
        pack();
    }

    /**
     * so
     * Adds a button to a container.
     *
     * @param c        the container
     * @param title    the button title
     * @param listener the action listener for the button
     */
    public void addButton(Container c, String title, ActionListener listener) {
        JButton button = new JButton(title);
        c.add(button);
        button.addActionListener(listener);
    }


    public synchronized void addBall() {
        // 一次创建50个ball
        for (int i = 0; i < 50; i++) {
            Ball ball = new Ball(comp.getBounds());
            comp.add(ball);

            Runnable ballThread = () -> {
                try {
                    for (int t = 1; t <= STEPS; t++) {
                        // Thread.currentThread()返回代表当前执行线程的 Thread 对象
                        //。
                        // 注意
                        // 有个类似的方法static boolean interrupted ()
                        // 这是一个静态方法。这一调用会产生副作用 —它将当前线程的中断状态重置为 false
                        // 这一点上, 而实例方法isInterrupted不改变中断状态,

                        if (!Thread.currentThread().isInterrupted()) {
                            ball.move(comp.getBounds());
                            comp.repaint();
                            // 不要在interrupt被设置时调用sleep方法
                            if (!Thread.currentThread().isInterrupted()) {
                                Thread.sleep(DELAY);
                            } else {
                                break;
                            }
                        }
//                        if (ball.getX() == comp.getBounds().getMaxX()/2 + Ball.XSIZE) {
//                            Thread.currentThread().interrupt();
//                        }
//                        if (ball.getY() == comp.getBounds().getMaxX()/2 + Ball.XSIZE) {
//                            Thread.currentThread().interrupt();
//                        }
                    }
                } catch (InterruptedException e) {
                    // 向线程发送中断请求//。//线程的中断状态将被设置为 true//。
                    // 如果目前该线程被一个 sleep//调用阻塞//，//那么//，
                    // InterruptedException 异常被抛出
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            };
            Thread t1 = new Thread(ballThread);
            t1.start();

        }
    }
}